package example.com.nexd.collectionsdk.sdk.collector.core;

import android.content.Context;
import android.hardware.Sensor;
import android.hardware.SensorEvent;
import android.hardware.SensorEventListener;
import android.hardware.SensorManager;

import example.com.nexd.collectionsdk.sdk.collector.Collector;
import example.com.nexd.collectionsdk.sdk.collector.CollectorConfig;
import example.com.nexd.collectionsdk.sdk.collector.SensorCollector;
import example.com.nexd.collectionsdk.sdk.collector.UserIdUtils;
import example.com.nexd.collectionsdk.sdk.collector.bean.SensorDataResult;
import example.com.nexd.collectionsdk.sdk.collector.listener.DefaultCollectorResultListener;
import example.com.nexd.collectionsdk.sdk.collector.listener.SensorCollectorResultListener;
import example.com.nexd.collectionsdk.sdk.utils.ObjectPool;


/**
 * SensorCollectorTask create by codingfish at 15/5/4
 * TODO:
 *
 * @Version V1.0
 */
abstract class SensorCollectorTask extends SensorCollector {

    private SensorManager sensorManager;
    private Sensor sensor;
    private SensorResultCallBack sensorResultCallBack;
    private ObjectPool<SensorDataResult> sensorDataResultObjectPool;

    protected SensorCollectorTask(Context context, SensorCollectorResultListener sensorCollectorResultListener, CollectorConfig collectorConfig) {
        super(context, sensorCollectorResultListener, collectorConfig);
        //初始化对象池
        ObjectPool.ObjectPoolFactory<SensorDataResult> sensorDataResultObjectPoolFactory = new ObjectPool.ObjectPoolFactory<SensorDataResult>() {
            @Override
            public SensorDataResult createObject() {
                return new SensorDataResult();
            }
        };

        sensorDataResultObjectPool = new ObjectPool<>(sensorDataResultObjectPoolFactory, 50);
    }


    protected abstract int getSensorType();

    @Override
    public boolean initilazeCollector() {
//        Debug.startMethodTracing("sensor_collector_task_initilazeCollector");
        if (sensorCollectorResultListener == null) {
            sensorCollectorResultListener = DefaultCollectorResultListener.getSensorDefaultCollectorResultListener();
        }

        if (collectorConfig == null) {
            collectorConfig = new CollectorConfig.Builder().build();
        }

        if (context == null) {
            sensorCollectorResultListener.onFailed(UserIdUtils.getInstance().getTask_Id(), Collector.FAILED_ID_CONTEXT_NULL, "context is null");
            return false;
        }
        sensorManager = (SensorManager) context.getSystemService(Context.SENSOR_SERVICE);
        if (sensorManager == null) {
            sensorCollectorResultListener.onFailed(UserIdUtils.getInstance().getTask_Id(), Collector.FAILED_ID_UNSUPPORTED_SENSOR_TYPE, "unsupported sensor");
            return false;
        }

        sensor = sensorManager.getDefaultSensor(getSensorType());

        if (sensor == null) {
            sensorCollectorResultListener.onFailed(UserIdUtils.getInstance().getTask_Id(), Collector.FAILED_ID_SCAN_MODE_NONE, "sensor 模块不可用");
            return false;
        }

        sensorResultCallBack = new SensorResultCallBack();

//        Debug.stopMethodTracing();

        return true;
    }

    @Override
    public boolean startCollector() {

//        Debug.startMethodTracing("sensor_collector_task_start_Collector");
        if (!sensorManager.registerListener(sensorResultCallBack, sensor, collectorConfig.sensor_delay)) {
            sensorCollectorResultListener.onFailed(UserIdUtils.getInstance().getTask_Id(), Collector.FAILED_ID_SCAN_MODE_NONE, "sensor 模块不可用");
            return false;
        }
//        Debug.stopMethodTracing();
        return true;
    }

    @Override
    public boolean stopCollector() {
        sensorManager.unregisterListener(sensorResultCallBack, sensor);

        sensorResultCallBack = null;
        sensor = null;
        sensorCollectorResultListener = null;
        sensorManager = null;
        sensorResultCallBack = null;

        if (sensorDataResultObjectPool != null) {
            sensorDataResultObjectPool.clear();
            sensorDataResultObjectPool = null;
        }
        return true;
    }

    private class SensorResultCallBack implements SensorEventListener {
        @Override
        public void onSensorChanged(SensorEvent event) {
//            Debug.startMethodTracing("sensor_collector_task_result_onSensorChanged");
            if (event != null) {
                SensorDataResult sensorDataResult = new SensorDataResult();
                sensorDataResult.setId(UserIdUtils.getInstance().getTask_Id());
                sensorDataResult.setAccuracy(event.accuracy);
                sensorDataResult.setSensor(event.sensor.toString());
                sensorDataResult.setSensorName(event.sensor.getName());
                sensorDataResult.setSensorType(event.sensor.getType());
                sensorDataResult.setTimestamp(event.timestamp);
                sensorDataResult.setValues(event.values);
                sensorCollectorResultListener.onSuccess(UserIdUtils.getInstance().getTask_Id(), sensorDataResult);
//                sensorDataResultObjectPool.free(sensorDataResult);
            } else {
                sensorCollectorResultListener.onFailed(UserIdUtils.getInstance().getTask_Id(), Collector.FAIED_ID_RESULT_NULL, "结果为空");
            }

//            Debug.stopMethodTracing();
        }

        @Override
        public void onAccuracyChanged(Sensor sensor, int accuracy) {
            if (sensor != null) {
                sensorCollectorResultListener.onAccuracyChanged(UserIdUtils.getInstance().getTask_Id(), sensor, accuracy);
            }

        }
    }
}
